#pragma once
#include <string>
#include "util/NonCopyable.h"
#include "io_mgr.h"
#include <memory>
using std::string;

#include <vector>
#include <mutex>
#include <deque>
using std::deque;
using std::vector;

//
// 我希望TCP服务器类中各连接的行为由各自独立处置。
// 仅在CTCPServer中做最基本的事务。
// 需要向业务层的对象提供ISockIOController接口，当业务层有数据需要发送的时候需要执行ISockIOController::enableWrite。
// 在这个对象收到数据处理完毕后需要发数据给客户端，那么需要执行enableWrite，否则epoll不会收到通知。
// 在这个对象中同时保存收、发数据缓冲区，整体的结构应该是这样的
//
class CServerNode 
    : public qcutil::NonCopyable
    , public std::enable_shared_from_this<CServerNode>
{
public:
    CServerNode(int fd, int fd_poll, IIOMgr* io_mgr);
    ~CServerNode();
public:
    // 将需要的数据添加到发送缓冲区中，当收到系统(即epoll)的可发送通知后由onSend实质发送。
    void sendData(const string& data);
    int getSock() { return m_fd; }
    void enableRead(bool is_enable);
    void enableWrite(bool is_enable);
    void onAccept(sockaddr_in addr);
    void onDataRecved(const string& data);
    // 在这里做发送数据的事情，如果数据全部发送完毕，需要执行enableWrite(false);
    void onSend();
    // 当epoll收到socket关闭的通知时调用这个通知业务层。
    void onSocketClosed();
    // 当epoll收到socket收发发生错误的时候调用这个通知业务层。
    // @TODO：目前如果是对方异常断开导致的socket错误则IO Manager无法收到通知。
    // 因为onSocketClosed将被先执行，并导致此对象被从IO Manager中移除。这应当视为是一个有必要处理的BUG。
    void onSocketError(int error_code);
    // 在这里获取需要发送的数据。
    void getDataToSend(string& data);
    // 在这里获取接收到的数据。
    void getDataRecved(string& data);
    // 关闭socket
    void closeSocket();
    // socket是否已经关闭
    bool isSocketClosed() { return m_socket_is_closed; }
private:
    int m_fd;
    bool m_socket_is_closed;
    uint32_t m_epoll_events;
    sockaddr_in m_addr;
    string m_internal_buf;
private:
    deque<string> m_send_buffers;
    std::recursive_mutex m_mutex_send;
    string m_recv_buffers;
    std::recursive_mutex m_mutex_recv;
    IIOMgr* m_io_mgr;
};

